﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;

namespace MoveShapeDemo
{
    public class Broadcaster
    {
        readonly static Lazy<Broadcaster> _instance=new Lazy<Broadcaster>(()=>new Broadcaster());
        private readonly TimeSpan BroadcastInterval = TimeSpan.FromMilliseconds(40);
        private readonly IHubContext _hubContext;
        private Timer _broadcastLoop;
        private ShapeModel _model;
        private bool _modelUpdated;

        public Broadcaster()
        {
            this._hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>();
            _model=new ShapeModel();
            _modelUpdated = false;

            _broadcastLoop=new Timer(BroadcastShap,null,BroadcastInterval,BroadcastInterval);
        }

        private void BroadcastShap(object state)
        {
            if (_modelUpdated)
            {
                this._hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(this._model);
                this._modelUpdated = false;
            }
        }

        public void UpdateShape(ShapeModel clientModel)
        {
            this._model = clientModel;
            this._modelUpdated = true;
        }

        public static Broadcaster Instance
        {
            get { return _instance.Value; }
        }
    }

    public class MoveShapeHub : Hub
    {
        private Broadcaster _broadcaster;

        public MoveShapeHub():this(Broadcaster.Instance)
        {
            
        }

        public MoveShapeHub(Broadcaster broadcaster)
        {
            this._broadcaster = broadcaster;
        }

        public void UpdateModel(ShapeModel clientModel)
        {
            clientModel.LastUpdatedBy = Context.ConnectionId;
            //Clients.AllExcept(clientModel.LastUpdatedBy).updateShape(clientModel);
            this._broadcaster.UpdateShape(clientModel);
        }
        
    }

    public class ShapeModel
    {
        [JsonProperty("left")]
        public double Left { get; set; }
        [JsonProperty("top")]
        public double Top { get; set; }
        //we don't want the client to get the "LastUpdatedBy" property
        [JsonIgnore]
        public string LastUpdatedBy { get; set; }
    }
}